<?php
namespace app\client\controller;
use app\common\lib\Redis;
use think\swoole\facade\Task;

class Cart extends Base {
    public function __construct() {
        parent::__construct();
    }
    
    //加入购物车
    public function add() {
        $params = request()->post();
        $chatId = isset($params['id']) ? intval($params['id']) : 0;
        if($chatId <= 0){
            return errorResult();
        }
        
        $quantity = isset($params['quantity']) ? intval($params['quantity']) : 1;
        if($quantity <= 0){
            return errorResult();
        }
        /* $goodsId = model('ChatGoods')->where(['chat_id' => $chatId])->value('id');
        if(!$goodsId){
            return errorResult();
        } */
        
        $userId = $this->userid;
        $cartModel = model('Cart');
        
        $cart = $cartModel->findOne(['user_id' => $userId, 'chat_id' => $chatId], ['id', 'quantity']);
        
        if($cart){ //已经有了
            $rs = $cartModel->modify(['id' => $cart['id']], ['quantity' => $cart['quantity'] + $quantity]);
            if(!$rs){
                return errorResult();
            }
        }else{
            $rs = $cartModel->add(['user_id' => $userId, 'quantity' => $quantity, 'chat_id' => $chatId, 'add_time' => time()]);
            if(!$rs){
                return errorResult();
            }
        }
        
        return successResult();
    }
    
    //更新购物车
    public function changeCart() {
        $params = request()->post();
        $cartId = isset($params['id']) ? intval($params['id']) : 0;
        if($cartId <= 0){
            return errorResult();
        }
        
        $quantity = isset($params['quantity']) ? intval($params['quantity']) : 1;
        if($quantity <= 0){
            return errorResult();
        }
        $cartModel = model('Cart');
        $cart = $cartModel->findOne(['id' => $cartId], ['user_id', 'quantity']);
        if(empty($cart) || $cart['user_id'] != $this->userid){
            return errorResult();
        }
        
        if($cart['quantity'] == $quantity){
            return successResult();
        }
        
        $rs = $cartModel->modify(['id' => $cartId], ['quantity' => $quantity]);
        if(!$rs){
            return errorResult();
        }
        return successResult();
    }
    
    //删除购物车
    public function delete() {
        $cartIds = request()->post('cartIds', []);
        if(!is_array($cartIds)){
            return errorResult();
        }
        
        foreach ($cartIds as &$cartId) {
            $cartId = intval($cartId);
            if($cartId <= 0){
                return errorResult();
            }
        }
        
        
        
        $model = model('Cart');
        $carts = $model->findAll(['id' => $cartIds], ['user_id']);
        if(empty($carts) || count($carts) != count($cartIds)){
            return errorResult();
        }
        
        foreach ($carts as $cart) {
            if($cart['user_id'] != $this->userid){
                return errorResult();
            }
        }
        
        $rs = $model->where(['id' => $cartIds])->delete();
        if(!$rs){
            return errorResult();
        }
        
        return successResult();
    }
    
    //用户购物车列表
    public function index() {
        $list = $this->_classifyCart();
        
        $storeList = [];
        $model = model('AgentRule');
        foreach ($list as $k => &$cart) {
            $storeId = $cart['store_id'];
            if($cart['isAgent'] == true) {
                continue;
            }
            
            if(isset($storeList[$storeId])) {
                $cart['store_agent_rule'] = $storeList[$storeId];
            }else {
                $rule = $model->findOne(['user_id' => $storeId], ['fee', 'slogan']);
                $storeList[$storeId] = $rule;
                $cart['store_agent_rule'] = $rule;
            }
            
        } 
        
        
        return successResult(['list' => $list]);
    }
    
    
    //生成订单
    public function toOrder() {
        $cartIds = request()->post('cartIds', []);
        if(empty($cartIds)){
            return errorResult();
        }
        
        $list = $this->_classifyCart($cartIds);
        $userId = $this->userid;
        $orderNo = getOrderNo($userId);
        
        Task::async(function() use($orderNo, $userId, $list){
            try {
                $orderData = [];
                foreach ($list as $item) {
                    $isAgent = $item['isAgent'];
                    $order = ['quantity' => 0, 'amount' => 0, 'is_agent' => $isAgent ? 1 : 0, 'goods' => []];
                    $item['store'] = json_decode($item['store'], true);
                    $order['store_id'] = $item['store']['user_id'];
                    foreach ($item['cart'] as $goods) {
                        $order['quantity'] += $goods['quantity'];
                        $pricce = $isAgent ? $goods['agent_price'] : $goods['sale_price'];
                        $order['amount'] += ($goods['quantity'] * $pricce );
                        
                        array_push($order['goods'], ['chat_id' => $goods['chat_id'], 'cover' => $goods['cover'], 'goods_name' => $goods['goods_name'], 'goods_no' => $goods['goods_no'], 'quantity' => $goods['quantity'], 'price' => $pricce]);
                    }
                    
                    array_push($orderData, $order);
                }
                
                $redis = new Redis();
                $redis->set('co_' . $orderNo, $orderData, 3600);
                $redis->close();
            } catch (\Exception $e) {
            }

            
            return true;
           
        });
        
        return successResult(['list' => $list, 'orderNo' => $orderNo]);
    }
    
    //结算
    public function settlement() {
        $params = request()->post();
        
        $orderNo = isset($params['orderNo']) ? trim($params['orderNo']) : '';
        if($orderNo === ''){
            return errorResult();
        }
        
        $addressId = isset($params['address']) ? intval($params['address']) : 0;
        if($addressId <= 0) {
            return errorResult();
        }
        
        $remarks = isset($params['remarks']) ? $params['remarks'] : [];
        if(!is_array($remarks)){
            return errorResult();
        }
        
        $cartIds = isset($params['cartIds']) ? $params['cartIds'] : [];
        if(!is_array($cartIds)){
            return errorResult();
        }
        
        unset($params);
        
        foreach ($remarks as $k => $item) {
            $remarks[$k] = trim(htmlspecialchars($item));
        }
        
        $userId = $this->userid;
        
        $address = model('DeliveryAddress')->findOne(['id' => $addressId], ['user_id', 'consignee', 'mobile', 'province', 'city', 'district', 'address']);
        
        if(!$address || $address['user_id'] != $userId){
            return errorResult();
        }
        
        $redis = new Redis();
        $orderData = $redis->get('co_' . $orderNo);
        if(empty($orderData)){
            $redis->close();
            return errorResult('订单信息已过期，请重新下单', 500);
        }
        
        $orderData = json_decode($orderData, true);
        if(empty($orderData)){
            return errorResult('订单信息已过期，请重新下单', 500);
        }
        
        $orderModel = model('Order');
        $orderGoodsModel = model('OrderGoods');
        
        $orderModel->startTrans();
        
        try {
            $time = time();
            
            foreach ($orderData as $k => $data) {
                $order = [
                    'order_no' => $orderNo . ($k < 10 ? '0' . $k : $k),
                    'order_type' => 1,
                    'user_id' => $userId,
                    'store_id' => $data['store_id'],
                    'is_agent' => $data['is_agent'],
                    'quantity' => $data['quantity'],
                    'amount' => $data['amount'],
                    'remarks' => $remarks[$k],
                    'consignee' => $address['consignee'],
                    'mobile' => $address['mobile'],
                    'province' => $address['province'],
                    'city' => $address['city'],
                    'district' => $address['district'],
                    'address' => $address['address'],
                    'consignee' => $address['consignee'],
                    'create_time' => $time
                ];
                
                $orderId = $orderModel->add($order);
                if(!$orderId){
                    $orderModel->rollback();
                    return errorResult('提交订单失败3');
                }
                
                $goodsData = $data['goods'];
                
                foreach ($goodsData as &$goods) {
                    $goods['order_id'] = $orderId;
                }
                
                $rs = $orderGoodsModel->addAll($goodsData);
                if(!$rs){
                    $orderModel->rollback();
                    return errorResult('提交订单失败2');
                }
                
            }
            
            $redis->del('co_' . $orderNo);
            $redis->close();
            
            if(!empty($cartIds)) {
                $model = model('Cart');
                Task::async(function() use($model, $cartIds) {
                    $model->where(['id' => $cartIds])->delete();
                    return true;
                });
            }
            
            
        } catch (\Exception $e) {
            $orderModel->rollback();
            $redis->close();
            return errorResult($e->getMessage());
            //return errorResult('提交订单失败1');
        }
        
        $orderModel->commit();
        
        return successResult('提交订单成功');
        
    }
    
    private function _classifyCart(array $cartIds = []) {
        $userId = $this->userid;
        $list = [];
        $where = 'user_id=' . $userId;
        if($cartIds){
            $where .= ' and id in (' . implode(',', $cartIds) . ')';
        }
       
        $carts = model('Cart')->where($where)->field(['id', 'quantity', 'chat_id'])->order('id desc')->select()->toArray();

        if($carts){
            $chatKeys = [];
            foreach ($carts as $cart) {
                array_push($chatKeys, redisChatKey($cart['chat_id']));
            }
            
            $redis = new Redis();
            
            $chats = $redis->mget($chatKeys);
            
            if(!empty($chats)) {
                for ($k = 0, $len = count($carts); $k < $len; $k ++) {
                    $chat = array_shift($chats);
                    $chat = json_decode($chat, true);
                    $carts[$k]['goods_no'] = $chat['goods_no'];
                    $carts[$k]['goods_name'] = $chat['goods_name'];
                    $carts[$k]['sale_price'] = $chat['sale_price'];
                    $carts[$k]['agent_price'] = $chat['agent_price'];
                    $carts[$k]['user_id'] = $chat['user_id'];
                    $carts[$k]['cover'] = $chat['cover'];
                }

                $storekeys = [];
                foreach ($carts as $k => $cart) {
                    $storeId = $cart['user_id'];
                    if(isset($list[$storeId])){
                        array_push($list[$storeId]['cart'], $cart);
                    }else{
                        array_push($storekeys, 'user_' . $storeId);
                        $list[$storeId] = ['cart' => [$cart]];
                    }
                    
                    
                }

                unset($carts);
                
                $storeList = $redis->mget($storekeys);
                $agentModel = model('Agent');
                foreach($list as $storeId => &$item) {
                    $item['isAgent'] = $agentModel->isAgent($userId, $storeId);
                    $item['store_id'] = $storeId;
                    $item['store'] = array_shift($storeList);
                }
                
                $redis->close();
            }
            
            
            
            $list = array_values($list);
        }
        
        return $list;
    }
    
    /* private function _classifyCart(array $cartIds = []) {
        $userId = $this->userid;
        $list = [];
        $where = 'a.user_id=' . $userId;
        if($cartIds){
            $where .= ' and a.id in (' . implode(',', $cartIds) . ')';
        }
        $carts = model('Cart')->alias('a')->join('__CHAT_GOODS__ b', 'a.goods_id=b.id')->join('__CHAT__ c', 'b.chat_id=c.chat_id')->field(['a.id', 'a.quantity', 'b.goods_no', 'b.goods_name', 'b.sale_price', 'b.agent_price', 'c.chat_id', 'c.user_id', 'c.cover'])->where($where)->order('a.id desc')->select()->toArray();
        
        if($carts){
            $storekeys = [];
            
            foreach ($carts as $cart) {
                $storeId = $cart['user_id'];
                if(isset($list[$storeId])){
                    array_push($list[$storeId]['cart'], $cart);
                }else{
                    array_push($storekeys, 'user_' . $storeId);
                    $list[$storeId] = ['cart' => [$cart]];
                }
            }
            
            unset($carts);
            
            $redis = new Redis();
            
            $storeList = $redis->mget($storekeys);
            $agentModel = model('Agent');
            foreach($list as $storeId => &$item) {
                $item['isAgent'] = $agentModel->isAgent($userId, $storeId);
                $item['store'] = array_shift($storeList);
            }
            
            $redis->close();
            
            $list = array_values($list);
        }
        
        return $list;
    } */
}











